/**
 * 
 */


package kulstats;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

/**
 * @author Steven, Ruben, Arnaud
 *
 */
public class UserManager {
	//private DAO dao;
	private static final DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
	private static final CourseManager courseManager = Registry.courseManager();
	
	public UserManager() { //DAO dao) {
		//this.dao = dao;
	}
	
	
	/*
	 * if return is 'null' then register has failed
	 * else it returns the entity of the registered user
	 * 
	 */
	public Entity registerUser(String name, String UserID, String mail, List<Course> courses, UserType usertype, String main, String side) {
		List<Entity> pq = getUserEntity(UserID);
		
		List<String> stringlist = new ArrayList<String>();
		for (int i = 0; i < courses.size(); i++){
			stringlist.add(courses.get(i).getCourseID());
		}
		
		
		Entity user = null;
		if (pq.size() == 0){
			user = new Entity("User");
			user.setProperty("Name", name);
			user.setProperty("Mail", mail);
			user.setProperty("UserID", UserID);
			user.setProperty("CourseIDs", stringlist);
			user.setProperty("UserType", usertype.toString());
			user.setProperty("Points", 0);
			user.setProperty("Main", main);
			user.setProperty("Side", side);
			datastore.put(user);
		}
		
		return user;
	}
	
	/*
	 * if return is 'null' then user does not exist
	 * else it returns the User object of the User entity in the database
	 * 
	 */
	public User getUser(String UserID) {
		List<Entity> pq = getUserEntity(UserID);
		User user = null;
	    if (pq.size() >= 1){
	    	Entity userentity = pq.get(0);
    		Map<String, Object> props = userentity.getProperties();
	    	if (UserType.valueOf((String) userentity.getProperty("UserType")) == UserType.STUDENT){
	    		List<String> cIDlist = (List<String>)props.get("CourseIDs");
	    		List<Course> courseList = new ArrayList<Course>();
	    		for (int i = 0; i < cIDlist.size(); i++)
	    		{
	    			courseList.add(courseManager.getCourseByID(cIDlist.get(i)));
	    		}
	    		user = new Student(userentity.getKey(), (String)props.get("Name")
	    				, (String)props.get("UserID"), (String)props.get("Mail"), courseList
	    				,((Number)props.get("Points")).intValue(), (String)props.get("Main"), (String)props.get("Side"));
	    	}
	    	else if (UserType.valueOf((String) userentity.getProperty("UserType")) == UserType.PROFESSOR){
	    		user = new Professor(userentity.getKey(), (String)props.get("Name")
	    				, (String)props.get("UserID"), (String)props.get("Mail"), (List<Course>)props.get("Courses")
	    				, (Integer)props.get("Points"));
	    	}
	    }
		
		return user;
	}
	
	public User getCurrentUser() {
    	UserService userService = UserServiceFactory.getUserService();
    	com.google.appengine.api.users.User aeUser = userService.getCurrentUser();
    	/*try {
    		return getUser(aeUser.getUserId());
    	}
    	catch(Exception e) {
    		return null;
    	}*/
    	if(aeUser != null)
    		return getUser(aeUser.getUserId());
    	return null;
	}
	
	public void updateUser(String name, String UserID, List<String> courses, UserType usertype, int points) {
		List<Entity> pq = getUserEntity(UserID);
		Entity userentity = null;
	    if (pq.size() >= 1){
	    	userentity = pq.get(0);
	    	userentity.setProperty("Name", name);
	    	userentity.setProperty("CourseIDs", courses);
			userentity.setProperty("UserType", usertype.toString());
	    	if (usertype == UserType.STUDENT){
	    		userentity.setProperty("Points", points);
	    	}
	    }
	    if(userentity!=null)
	    {
	    	datastore.put(userentity);   
	    }
	}
	
	/*
	 * if return is 'null' then user does not exist
	 * else it returns the list of user that has the given name 'name' (NOTE: should only be 1 in theory)
	 * 
	 */
	public List<Entity> getUserEntity(String par) {
		Query q = new Query("User");
		q.addFilter("UserID", Query.FilterOperator.EQUAL, par);
		List<Entity> pq = datastore.prepare(q).asList(FetchOptions.Builder.withDefaults());
		return pq;
	}
	
	public List<Entity> getAllUsers() {
		Query q = new Query("User");
		List<Entity> pq = datastore.prepare(q).asList(FetchOptions.Builder.withDefaults());
		return pq;
	}
}



